package service

import (
	sqlc "bgs/db/sqlc"
	"bgs/service/model"
	"bgs/util"
	"context"
	"encoding/json"
	"fmt"
	"time"
)

type LoggingBCoinForActivityAwardParam struct {
	UserID                      int64
	ActivityPtr                 *sqlc.Activity
	ActivityUserAwardExtInfoPtr *model.ActivityUserAwardExtInfo
}

type loggingBCoinForActivityAwardExt struct {
	BrandName    string    `json:"brand_name"`
	ActivityID   int64     `json:"activity_id"`
	ActivityName string    `json:"activity_name"`
	ActivityType string    `json:"activity_type"`
	Got          time.Time `json:"got"`
	Scene        string    `json:"scene"`
}

// LoggingAccountForOrderBonusProfit 用户参与活动星币奖励记账
func (s *UserServiceImp) LoggingBCoinForActivityAward(ctx context.Context, q *sqlc.Queries, p LoggingBCoinForActivityAwardParam) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("==begin 用户参与活动星币奖励记账")

	var scene string
	switch sqlc.EmActivityType(p.ActivityUserAwardExtInfoPtr.ActivityType) {
	case sqlc.EmActivityTypeCheckIn1:
		scene = "签到奖励星币"
	case sqlc.EmActivityTypeLottery1:
		scene = "抽奖活动中奖奖励星币"
	}

	now := time.Now()

	extInfoBytes, marshalErr := json.Marshal(&loggingBCoinForActivityAwardExt{
		BrandName:    p.ActivityUserAwardExtInfoPtr.BrandName,
		ActivityID:   p.ActivityPtr.ID,
		ActivityName: p.ActivityUserAwardExtInfoPtr.ActivityName,
		ActivityType: p.ActivityUserAwardExtInfoPtr.ActivityType,
		Got:          now,
		Scene:        scene,
	})
	if marshalErr != nil {
		err = marshalErr
		return
	}

	loggingParam := loggingBCoinParam{
		UserID:   p.UserID,
		BrandID:  p.ActivityPtr.BrandID,
		IsIn:     true,
		Category: sqlc.EmUserBCoinLogCategoryActivityAward,
		Quantity: int64(p.ActivityUserAwardExtInfoPtr.AwardInfo.Coins),
		Subject:  fmt.Sprintf("用户参与活动星币奖励-%s", p.ActivityUserAwardExtInfoPtr.ActivityName),
		ExtInfo:  string(extInfoBytes),
	}

	err = s.loggingBCoin(ctx, q, loggingParam)
	if err != nil {
		return
	}
	slog.Infof("1 用户星币变动日志(明细账)用户参与活动星币奖励 ok")

	slog.Infof("==end 用户参与活动星币奖励记账 ok")
	return
}

// loggingBCoinParam 记录用户星币变动日志参数
type loggingBCoinParam struct {
	UserID   int64
	BrandID  int64
	IsIn     bool
	Category sqlc.EmUserBCoinLogCategory
	Quantity int64
	Subject  string
	ExtInfo  string
}

// loggingBCoin 记录用户星币变动日志
func (s *UserServiceImp) loggingBCoin(ctx context.Context, q *sqlc.Queries, p loggingBCoinParam) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	_, err = q.CreateUserBCoinLog(ctx, sqlc.CreateUserBCoinLogParams{
		UserID:   p.UserID,
		BrandID:  p.BrandID,
		IsIn:     p.IsIn,
		Category: string(p.Category),
		Quantity: util.Int64IfThenElse(p.IsIn, 1, -1) * p.Quantity,
		Subject:  p.Subject,
		ExtInfo:  p.ExtInfo,
	})
	if err != nil {
		return
	}
	slog.Infof("创建用户星币变动日志 ok")
	return
}
